/**
 * Copyright (c) 2018-present, Chen Guodong
 * All rights reserved.
 *
 * @flow
 */


<template>
  <div class="content">
    <el-dialog 
      :title="selectedMarkItem.title" 
      :visible.sync="infoModalVis"
      @open="infoModalOpen"
      width='800px'
    >
      <ModalContent :data="modalInfo"></ModalContent>
    </el-dialog>
    <div class="header">
      <div class="title">伍家岗智慧征收数据管理平台</div>
      <div class="users">
        管理员
        <img src="../../assets/img/head.png" alt="">
      </div>
    </div>
    <div class="main">
      <ChartInfo></ChartInfo>
      <Search 
        :searchInfo="getInfo" 
        :hanlderSearchItem="hanlderSearchItem" 
        :leaveSearchItem="leaveSearchItem"
        :hoverSearchItem="hoverSearchItem"
        :clearShowResult="clearShowResult"
        :inEditStatus="inEditStatus"
        :pageInfo="pageInfo" 
        :changePage="changePage" 
        :searchResult="showResult"
        :changeContentVis="changeContentVis"
        :contentVis="contentVis"
        :opneModal="opneModal"
      >
      </Search>
      <div class="map" id="map">
        <Legend></Legend>
      </div>
      <div class="types-box">
        <Types :getInfo="getInfo"></Types>
      </div>
      <div class="edit-box" v-show="editVis">
        <ul>
          <el-button @click="editMark" type="info" size="small">编辑点</el-button>
          <el-button @click="edidArea" type="primary" size="small">编辑面</el-button>
          <el-button @click="createArea" type="primary" size="small">新增面</el-button>
          <el-button @click="clearEdit" type="warning" size="small">清空</el-button>
          <el-button @click="quitEditStatus" type="danger" size="small">退出</el-button>
          <el-button @click="saveEdit" type="success" size="small">保存</el-button>
        </ul>
      </div>
    </div>
  </div>
</template>

<script>
// components
import { lazyAMapApiLoaderInstance } from "vue-amap";
import ModalContent from "./ModalContent";
import Search from "../../components/Search";
import Detail from "../../components/Detail";
import ChartInfo from "./ChartInfo";
import Types from "../../components/Types";
import Legend from "../../components/Legend";
import config from "../../utils/config.js";
import _ from "lodash";
import { reqMapInfo, reqProjectInfo } from "../../api/index.js";
import { showMessage } from "../../utils/index.js";

export default {
  name: "app",
  data() {
    return {
      Map: "", //地图
      allInfo: [], //所有点的原始信息
      pointers: {}, //所有点渲染的实例化对象, {id: pointerObj}
      areas: {}, //所有点渲染的面积实例
      searchResult: [], //所有项目的信息
      showResult: [], //当前页显示的项目细腻系
      contentVis: false, //搜索结果是否显示
      infoModalVis: false, //点击mark弹出的模态框可见性
      selectedMarkItem: {}, //当前点击的模态框信息
      modalInfo: {}, //模态框要展示的内容
      editObj: {}, //右键选中的目标
      editVis: false, //是否进入编辑状态
      editNewObj: { mark: null, area: null }, //暂存的新编辑的对象
      pageInfo: {
        //页码信息
        curPage: 1,
        pageTotal: 10,
        total: 0
      },
      locaitonImage: require("../../assets/img/location-icon.png")
    };
  },
  computed: {},
  watch: {
    showResult: function(data, oldData) {
      const self = this;
      const s = data;
      const o = oldData;
      const z = this.Map.getZoom();
      //恢复原图标
      if (o && o.length > 0) {
        o.map((item, index) => {
          const m = self.pointers[item.seqno];
          if (m) {
            m.setIcon(
              new AMap.Icon({
                size: [17, 27],
                imageSize: [300, 300],
                imageOffset: new AMap.Pixel(-180, -166),
                image: this.locaitonImage
              })
            );
          }
        });
      }
      //显示新图标
      if (s && s.length > 0) {
        s.map((item, index) => {
          const m = self.pointers[item.seqno];
          if (m) {
            m.setIcon(
              new AMap.Icon({
                size: [18, 27],
                imageSize: [300, 300],
                imageOffset: new AMap.Pixel(-18 * index, -139),
                image: this.locaitonImage,
                expandZoomRange: true,
                skyColor: "#ff0000"
              })
            );
          }
        });
      }
    }
  },
  components: {
    Search,
    Detail,
    Types,
    ModalContent,
    ChartInfo,
    Legend
  },
  methods: {
    // 地图初始化
    async initMap() {
      const self = this;
      this.Map = new AMap.Map("map", {
        mapStyle: "amap://styles/549409facc090ed9eeb9f75cbd30489e",
        resizeEnable: true,
        center: config.center, //[longitude经度，latitude纬度]
        zoom: config.zoom,
        zooms: config.zooms
      });
      var scale = new AMap.Scale({
          visible: true
        }),
        toolBar = new AMap.ToolBar({
          visible: true,
          position: "RT"
        });
      this.Map.addControl(scale);
      this.Map.addControl(toolBar);
      const all = await reqMapInfo(); //获取全部点位信息进行渲染
      this.allInfo = all.data;
      this.searchResult = all.data;
      await this.initAllPointer(); //初始化所有的点
      await this.initAllArea(); //初始化所有的面积

      // 初始化右键菜单
      self.contextMenu = new AMap.ContextMenu(); //创建右键菜单
      self.contextMenu.addItem(
        "编辑",
        function() {
          self.inEditStatus();
        },
        0
      );

      // 监听地图zoom变化
      this.Map.on("zoomchange", () => {
        if (this.editNewObj.area) return;
        const zoom = this.Map.getZoom();
        const showResultSeqno = this.showResult.map(item => item.seqno);
        if (zoom < config.middleZoom) {
          for (var item in self.pointers) {
            // 清空所有title
            self.pointers[item].setLabel({
              content: ""
            });
            // 清空所有areas
            for (var item in self.areas) {
              self.areas[item].hide();
            }
          }
        } else {
          for (var item in self.pointers) {
            self.pointers[item].setLabel({
              //修改label相对于maker的位置
              offset: new AMap.Pixel(22, 3),
              content: `<div class="label-info" style="background:${this.getColorByStatus(
                self.allInfo.filter(b => b.seqno == item)[0].status
              )}">${
                self.allInfo.filter(b => b.seqno == item)[0].shortTitle
              }</div>`
            });
            // 显示所有areas
            for (var item in self.areas) {
              self.areas[item].show();
            }
          }
        }
      });
      // 根据地图中的点自适应显示
      var newCenter = this.Map.setFitView();
    },
    // 获取搜索的出来的信息
    async getInfo(data) {
      const r = await reqMapInfo(data);
      this.$set(this.pageInfo, "total", r.data ? r.data.length : 0);
      this.searchResult = r.data;
      this.setShowResult();
      this.changeContentVis(true);
      this.initAllPointer();
      this.initAllArea();
    },
    changeContentVis(data) {
      this.contentVis = data;
    },
    // 设置当前需要展示的信息
    setShowResult() {
      const p = this.pageInfo;
      const r = this.searchResult;
      const d = _.cloneDeep(r);
      if (d && d.length > 0) {
        this.showResult = d.splice((p.curPage - 1) * p.pageTotal, p.pageTotal);
      } else {
        this.showResult = [];
      }
    },
    // 清空当前需要展示的信息
    clearShowResult() {
      this.showResult = [];
    },
    // 点击搜索栏中的item
    hanlderSearchItem(data) {
      this.Map.setFitView(this.pointers[data.seqno]);
      this.opneModal(data);
    },
    // 当鼠标移动到搜索结果上时
    hoverSearchItem(data) {
      console.log("当鼠标移动到搜索结果上时", data);
    },
    // 当鼠标移开搜索结果上时
    leaveSearchItem(data) {
      console.log("当鼠标移开搜索结果上时", data);
    },
    // 改变页码
    changePage(data) {
      this.$set(this.pageInfo, "curPage", data);
      this.setShowResult();
    },
    // 根据项目类别获取不同的颜色
    getColorByStatus(status) {
      return config.statusColor[status];
    },
    // 初始化所有点
    initAllPointer() {
      const self = this;
      // 先清除所有点位
      for (let i in self.pointers) {
        this.Map.remove(self.pointers[i]);
      }
      self.pointers = {};
      //再从新渲染新的点
      // console.log('从新渲染的点', this.allInfo);
      if (!this.searchResult || this.setShowResult.length < 0) return;
      this.searchResult.map(item => {
        if (item.location.length < 2) {
          // console.log('小于2');
          console.log("没有点位信息!!!");
        } else {
          let marker = new AMap.Marker({
            icon: new AMap.Icon({
              size: [17, 27],
              imageSize: [300, 300],
              imageOffset: new AMap.Pixel(-180, -166),
              image: this.locaitonImage
            }),
            position: item.location,
            offset: new AMap.Pixel(-13, -30)
          });
          marker.setLabel({
            //修改label相对于maker的位置
            offset: new AMap.Pixel(22, 5),
            content: `<div class="label-info" style="background:${this.getColorByStatus(
              item.status
            )}">${item.shortTitle}</div>`
          });
          marker.setMap(this.Map);
          self.pointers[item.seqno] = marker;
          marker.on(
            "click",
            function() {
              self.opneModal(item);
            },
            self
          );
          //绑定鼠标右击事件——弹出右键菜单
          marker.on(
            "rightclick",
            function(e) {
              self.editObj = item;
              self.contextMenu.open(self.Map, e.lnglat);
            },
            self
          );
        }
      });
      this.Map.setFitView();
    },
    // 初始化所有区域的面积
    initAllArea() {
      const self = this;
      // 先清除所有面
      for (let i in self.areas) {
        this.Map.remove(self.areas[i]);
      }
      self.areas = {};
      if (!this.searchResult || this.setShowResult.length < 0) {
        console.log("没有面积信息!");
        return;
      }
      //再从新渲染新的面
      this.searchResult.map(item => {
        if (item.area && item.area.length > 0) {
          var path = [];
          item.area.map(b => {
            path.push([Number(b.lng), Number(b.lat)]);
          });
          const area = new AMap.Polygon({
            path: path,
            strokeOpacity: 0.8,
            fillOpacity: 0.4,
            strokeWeight: 1,
            fillColor: this.getColorByStatus(item.status),
            strokeColor: this.getColorByStatus(item.status),
            zIndex: 99
          });
          area.setMap(self.Map);
          self.areas[item.seqno] = area;
          //绑定鼠标右击事件——弹出右键菜单
          area.on(
            "rightclick",
            function(e) {
              self.editObj = item;
              self.contextMenu.open(self.Map, e.lnglat);
            },
            self
          );
        }
      });
    },
    opneModal(data) {
      this.infoModalVis = true;
      this.selectedMarkItem = data;
    },
    // 当模态框打开后的动作
    async infoModalOpen() {
      const r = await reqProjectInfo({ seqno: this.selectedMarkItem.seqno });
      this.modalInfo = r.data;
    },
    // 退出编辑模式
    quitEditStatus() {
      this.clearEdit();
      this.editVis = false;
    },
    // 编辑点
    editMark() {
      const self = this;
      const oldMark = self.pointers[self.editObj.seqno];
      if (self.editNewObj.mark || self.editNewObj.area) {
        showMessage(self, "正在编辑中!", "warning", "提示");
        return;
      }
      // 如果有点 复制一个mark并隐藏以前的mark, 并显示在地图中可以移动
      if (oldMark) {
        self.editNewObj.mark = new AMap.Marker({
          icon: oldMark.getIcon(),
          position: oldMark.getPosition(),
          offset: oldMark.getOffset()
        });
        oldMark.hide();
        self.editNewObj.mark.setMap(self.Map);
        self.editNewObj.mark.setDraggable(true);
      } else {
        showMessage(self, "请用鼠标点击地图生成新的坐标点", "success");
        // 如果原来没有点的话则新建一个点
        const mouseTool = new AMap.MouseTool(self.Map);
        mouseTool.marker();
        AMap.event.addListener(mouseTool, "draw", function(e) {
          showMessage(
            self,
            "如果想调整坐标点位置请用鼠标移动新生成的图标",
            "success"
          );
          e.obj.setDraggable(true);
          self.editNewObj.mark = e.obj;
          mouseTool.close(true);
        });
      }
    },
    //清空所有编辑对象并显示原来的点和面
    showOldCLearNew() {
      const self = this;
      for (let i in self.editNewObj) {
        if (self.editNewObj[i]) {
          if (i === "mark") {
            self.editNewObj[i].setDraggable(false);
          }
          if (i === "area") {
            self.polyEditor.close();
          }
          self.editNewObj[i].hide(); //隐藏编辑的点或者面
          self.editNewObj[i] = null; //并在缓存中清除点
        }
      }
      const oldMark = self.pointers[self.editObj.seqno];
      const oldArea = self.areas[self.editObj.seqno];
      console.log("oldMark", oldMark);
      //显示原来的点
      if (oldMark) {
        console.log("显示点");
        oldMark.show();
      }
      //显示原来的面
      if (oldArea) {
        oldArea.show();
      }
    },
    clearEdit() {
      this.showOldCLearNew();
    },
    saveEdit() {
      const self = this;
      const success = true;
      // 如果保存成功则执行以下操作
      if (success) {
        for (let i in self.editNewObj) {
          if (self.editNewObj[i]) {
            if (i === "mark") {
              let newPosition; //用于更新数据中的定位点
              //点
              self.editNewObj[i].setDraggable(false);
              self.editNewObj[i].hide();
              const oldMark = self.pointers[self.editObj.seqno];
              // 如果旧的mark存在则隐藏新的mark显示旧的mark, 如果旧mark不存在,则保存新mark到数据集中
              if (oldMark) {
                newPosition = self.editNewObj[i].getPosition();
                oldMark.setPosition(newPosition);
                oldMark.show();
                self.editNewObj[i] = null;
                // 更新数据
              } else {
                let pointer = self.pointers[self.editObj.seqno];
                self.pointers[self.editObj.seqno] = self.editNewObj[i];
                pointer = self.editNewObj[i];
                newPosition = pointer.getPosition();
                self.editNewObj[i] = null;
                pointer.setIcon(
                  new AMap.Icon({
                    size: [17, 27],
                    imageSize: [300, 300],
                    imageOffset: new AMap.Pixel(-180, -166),
                    image: self.locaitonImage
                  })
                );
                pointer.setLabel({
                  //修改label相对于maker的位置
                  offset: new AMap.Pixel(22, 5),
                  content: `<div class="label-info" style="background:${this.getColorByStatus(
                    self.editObj.status
                  )}">${self.editObj.shortTitle}</div>`
                });
                pointer.on(
                  "click",
                  function() {
                    self.opneModal(self.editObj);
                  },
                  self
                );
                //绑定鼠标右击事件——弹出右键菜单
                pointer.on(
                  "rightclick",
                  function(e) {
                    self.editObj = self.editObj;
                    self.contextMenu.open(self.Map, e.lnglat);
                  },
                  self
                );
                // 保存成功,更新数据并显示
                pointer.show();
              }
              self.updateItemInfo("location", [
                newPosition.lng,
                newPosition.lat
              ]);
            }
            if (i === "area") {
              self.areas[self.editObj.seqno] = self.editNewObj[i];
              self.areas[self.editObj.seqno].on(
                "click",
                function() {
                  self.opneModal(self.editObj);
                },
                self
              );
              //绑定鼠标右击事件——弹出右键菜单
              self.areas[self.editObj.seqno].on(
                "rightclick",
                function(e) {
                  self.editObj = self.editObj;
                  self.contextMenu.open(self.Map, e.lnglat);
                },
                self
              );
              // 保存成功,更新数据并显示
              self.updateItemInfo(
                "area",
                self.editNewObj[i]
                  .getPath()
                  .map(item => ({ lng: item.lng, lat: item.lat }))
              );
            }
            self.quitEditStatus();
          }
        }
      }
    },
    // 进去编辑状态
    inEditStatus(data) {
      const self = this;
      // 如果是点击菜单栏进入编辑模式
      if (data) {
        self.editObj = data;
      }
      if (self.editVis) {
        showMessage(self, "你正处在编辑状态,请不要再次编辑!", "warning");
        return;
      }
      self.editVis = true;
      if (self.pointers[self.editObj.seqno]) {
        self.Map.setFitView(self.pointers[self.editObj.seqno]);
      } else {
        showMessage(self, "还没有点位信息,请自己添加哦!", "warning");
      }
    },
    // update 点位信息
    updateItemInfo(type, value) {
      const self = this;
      // 根据newPosition更新数据
      if (self.allInfo && self.allInfo.length > 0) {
        self.allInfo.map((item, index) => {
          if (item.seqno === self.editObj.seqno) {
            self.allInfo[index][type] = value;
          }
        });
      }
      if (self.searchResult && self.searchResult.length > 0) {
        self.searchResult.map((item, index) => {
          if (item.seqno === self.editObj.seqno) {
            self.searchResult[index][type] = value;
          }
        });
      }
      if (self.showResult && self.showResult.length > 0) {
        self.showResult.map((item, index) => {
          if (item.seqno === self.editObj.seqno) {
            self.showResult[index][type] = value;
          }
        });
      }
    },
    // 编辑面
    edidArea() {
      const self = this;
      const oldArea = self.areas[self.editObj.seqno];
      if (self.editNewObj.mark || self.editNewObj.area) {
        showMessage(self, "正在编辑中!", "warning", "提示");
        return;
      }
      console.log("oldArea", oldArea);
      if (oldArea) {
        // 复制一个area并隐藏原来的area
        self.editNewObj.area = new AMap.Polygon({
          path: oldArea.getOptions().path.map(item => [item.lng, item.lat]),
          strokeOpacity: 0.8,
          fillOpacity: 0.4,
          strokeWeight: 1,
          fillColor: oldArea.getOptions().fillColor,
          strokeColor: oldArea.getOptions().statusColor,
          zIndex: 99
        });
        oldArea.hide();
        self.editNewObj.area.setMap(self.Map);
        self.polyEditor = new AMap.PolyEditor(self.Map, self.editNewObj.area);
        self.polyEditor.open();
        self.polyEditor.on("addnode", function(event) {
          showMessage(self, "添加节点!", "success", "提示");
          self.editNewObj.area = event.target;
        });

        self.polyEditor.on("adjust", function(event) {
          self.editNewObj.area = event.target;
        });
        self.polyEditor.on("removenode", function(event) {
          showMessage(self, "移除节点!", "success", "提示");
          self.editNewObj.area = event.target;
        });
        self.polyEditor.on("end", function(event) {
          showMessage(self, "编辑完成!", "success", "提示");
          self.editNewObj.area = event.target;
        });
      } else {
        self.createArea();
      }
    },
    // 新增面
    createArea() {
      const self = this;
      const oldArea = self.areas[self.editObj.seqno];
      if (self.editNewObj.area) {
        showMessage(
          self,
          "请先退出编辑状态或者清空现有图形!",
          "warning",
          "警告"
        );
        return;
      }
      // 如果原来的面存在,则先隐藏原来的面
      if (oldArea) {
        oldArea.hide();
      }
      self.mouseTool = new AMap.MouseTool(self.Map);
      const drawPolygon = self.mouseTool.polygon();
      showMessage(self, "请点击地图开始绘制多边形!", "success");
      //添加事件
      AMap.event.addListener(self.mouseTool, "draw", function(e) {
        console.log("e", e);
        self.mouseTool.close(true);
        let newArea = new AMap.Polygon({
          path: e.obj.getPath().map(item => [item.lng, item.lat]),
          strokeOpacity: 0.8,
          fillOpacity: 0.4,
          strokeWeight: 1,
          fillColor: self.getColorByStatus(self.editObj.status),
          strokeColor: self.getColorByStatus(self.editObj.status),
          zIndex: 99
        });
        self.editNewObj.area = newArea;
        self.editNewObj.area.setMap(self.Map);
        self.polyEditor = new AMap.PolyEditor(self.Map, self.editNewObj.area);
        self.polyEditor.open();
        self.polyEditor.on("addnode", function(event) {
          showMessage(self, "添加节点!", "success", "提示");
          self.editNewObj.area = event.target;
        });

        self.polyEditor.on("adjust", function(event) {
          self.editNewObj.area = event.target;
        });
        self.polyEditor.on("removenode", function(event) {
          showMessage(self, "移除节点!", "success", "提示");
          self.editNewObj.area = event.target;
        });
        self.polyEditor.on("end", function(event) {
          showMessage(self, "编辑完成!", "success", "提示");
          self.editNewObj.area = event.target;
        });
      });
    }
  },
  mounted() {
    //初始化地图
    lazyAMapApiLoaderInstance.load().then(() => {
      this.initMap();
    });
  }
};
</script>

<style lang="less" scoped>
@import "../../utils/theme.less";

.content {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  width: 100%;
  height: 100%;
  position: relative;
  .header {
    height: 80px;
    width: 100%;
    background: @primary;
    z-index: 100;
    text-align: center;
    .header,
    .title {
      display: inline-block;
      height: 100%;
    }
    .title {
      font-size: 32px;
      padding: 10px 10px 10px 20px;
      line-height: 60px;
      float: left;
      font-weight: bold;
      color: #fff;
    }
  }
  .main {
    width: 100%;
    height: calc(~"100% - 80px");
    position: relative;
    overflow: hidden;
  }
}
#map {
  width: 100%;
  height: 100%;
  z-index: 1;
}
.detailContent {
  padding: 10px;
  position: absolute;
  top: 58px;
  left: 20px;
  z-index: 10002;
  width: 329px;
}
.types-box {
  position: absolute;
  top: 20px;
  left: 0px;
  width: 100%;
  z-index: 2;
  height: 80px;
  font-size: 16px;
  display: flex;
  justify-content: center;
}
.label-info {
  padding: 3px;
  background: @primary;
  font-weight: 500;
}
.users {
  float: right;
  padding: 10px;
  line-height: 60px;
  box-sizing: border-box;
  font-size: 16px;
  color: #fff;
  font-weight: 500;
  img {
    height: 50px;
    width: 50px;
    border-radius: 50px;
    vertical-align: middle;
    margin-left: 10px;
  }
}
.edit-box {
  position: absolute;
  left: 0;
  bottom: 20px;
  width: 100%;
  // height: 30px;
  // background: #fff;
  text-align: center;
  z-index: 12;
  ul {
    li {
      display: inline-block;
      height: 100%;
      padding: 5px 10px;
      line-height: 20px;
      background: @primary;
      border-radius: 5px;
      color: #fff;
      margin-right: 6px;
      font-size: 12px;
      cursor: pointer;
    }
  }
}
</style>

